// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT

import { DemoPalette, PushButton } from "./common.slint";

export struct PrinterQueueItem  {
    status: string,
    progress: int,
    title: string,
    owner: string,
    pages: int,
    size: string, // number instead and format in .slint?
    submission-date: string
}

export global PrinterQueue  {
    in property <[PrinterQueueItem]> printer-queue: [
        { status: "printing", progress: 63, title: "210106-FinalPresentation.pdf", owner: "info@slint.dev", pages: 6, size: "143kb", submission-date: "11:41 25/01/21" },
        { status: "waiting", title: "Adressliste.docx", owner: "info@slint.dev", pages: 6, size: "143kb", submission-date: "11:41 25/01/21" },
        { status: "waiting", title: "Salaries.pdf", owner: "info@slint.dev", pages: 6, size: "143kb", submission-date: "11:41 25/01/21" },
    ];

    public pure function statusString(status: string) -> string {
        if (status == "printing") {
            @tr("PRINTING")
        } else if (status == "waiting") {
            @tr("WAITING...")
        } else {
            @tr("Unknown job status")
        }
    }

    callback start-job(string);
    callback cancel-job(int);
    callback pause-job(int);
}


component PrintQueueDetailsLabel inherits Text {
    font-weight: 500;
    color: DemoPalette.control-foreground;
    horizontal-stretch: 0;
    font-size: DemoPalette.base-font-size * 0.9375;
}

component PrintQueueSeparator inherits Rectangle {
    height: 1px;
    border-width: 1px;
    border-color: #BDC0D1;
    horizontal-stretch: 2;
}

component PrintDetails inherits GridLayout {
    in property <PrinterQueueItem> queue-item;

    spacing: 3px;

    Row {
        PrintQueueDetailsLabel {
            text: @tr("Job Owner");
        }

        Text {
            text: root.queue-item.owner;
            color: DemoPalette.secondary-foreground-color;
            overflow: elide;
            horizontal-stretch: 1;
            font-size: DemoPalette.base-font-size * 0.9375;
        }
    }
    Row {
        PrintQueueSeparator {
            colspan: 2;
        }
    }

    Row {
        PrintQueueDetailsLabel {
            text: @tr("Pages");
        }

        Text {
            text: root.queue-item.pages;
            color: DemoPalette.secondary-foreground-color;
            overflow: elide;
            horizontal-stretch: 1;
            font-size: DemoPalette.base-font-size * 0.9375;
        }
    }

    Row {
        PrintQueueSeparator {
            colspan: 2;
        }
    }

    Row {
        PrintQueueDetailsLabel {
            text: @tr("Size");
        }

        Text {
            text: root.queue-item.pages;
            color: DemoPalette.secondary-foreground-color;
            overflow: elide;
            horizontal-stretch: 1;
            font-size: DemoPalette.base-font-size * 0.9375;
        }
    }

    Row {
        PrintQueueSeparator {
            colspan: 2;
        }
    }

    Row {
        PrintQueueDetailsLabel {
            text: @tr("Submitted");
        }

        Text {
            text: root.queue-item.submission-date;
            color: DemoPalette.secondary-foreground-color;
            overflow: elide;
            horizontal-stretch: 1;
            font-size: DemoPalette.base-font-size * 0.9375;
        }
    }
}

component NarrowPrintQueueElement inherits Rectangle {
    in property <PrinterQueueItem> queue-item;
    in-out property <bool> expanded;

    callback show-job-details();

    private property <float> expanded-opacity: 0;

    border-color: DemoPalette.secondary;
    border-radius: 14px;
    border-width: 2px;
    background: DemoPalette.background;
    clip: true;
    height: always-visible.min-height + layout.padding * 2;

    states [
        expanded when root.expanded : {
            height: layout.min-height;
            expanded-opacity: 1;

            in {
                animate height { duration: 200ms; easing: ease; }
                animate expanded-opacity { duration: 200ms; }
            }
            out {
                animate height { duration: 200ms; easing: ease; }
                animate expanded-opacity { duration: 200ms; }
            }
        }
    ]

    TouchArea {
        clicked => {
            root.expanded = !root.expanded;
        }
    }

    Rectangle {
        height: 100%;
        layout := VerticalLayout {
            padding: root.border-radius;
            spacing: 4px;
            alignment: start;

            always-visible := VerticalLayout {
                padding: 0;
                spacing: parent.spacing;

                Text {
                    // TODO: text-transform: uppercase
                    text: {
                        if (root.queue-item.progress > 0) {
                            @tr("{}% - {}",root.queue-item.progress, PrinterQueue.statusString(root.queue-item.status))
                        } else {
                            PrinterQueue.statusString(root.queue-item.status)
                        }
                    }
                    color: DemoPalette.text-secondary;
                    font-size: DemoPalette.base-font-size * 0.75;
                    font-weight: 800;
                    letter-spacing: 1.56px;
                }

                Text {
                    text: root.queue-item.title;
                    overflow: elide;
                    color: DemoPalette.text-primary;
                    font-weight: 800;
                    font-size: DemoPalette.base-font-size * 1.125;
                }
            }

            if (root.expanded || root.expanded-opacity > 0) : PrintDetails {
                padding: 0px;
                padding-bottom: root.border-radius / 2;
                queue-item: root.queue-item;
                opacity: root.expanded-opacity;
            }

            if (root.expanded || root.expanded-opacity > 0) : HorizontalLayout {
                Rectangle {
                    horizontal-stretch: 0;
                    width: 10%;
                }

                PushButton {
                    clicked => {
                        root.show-job-details();
                    }
                    opacity: root.expanded-opacity;
                    text: @tr("More   ");
                }

                Rectangle {
                    horizontal-stretch: 0;
                    width: 10%;
                }
            }
        }
    }
}

component NarrowPrinterQueueList inherits Flickable {
    callback show-job-details(int);

    VerticalLayout {
        alignment: start;
        padding: 0px;
        spacing: 13.5px;

        for queue-item[idx] in PrinterQueue.printer-queue: NarrowPrintQueueElement {
            show-job-details => {
                root.show-job-details(idx)
            }

            width: root.width;
            queue-item: queue-item;
        }
    }
}

component ProgressBar inherits Rectangle {
    in property <int> progress;

    // FIXME: The intermediate rectangle is needed to allow the surrounding
    // layout to freely resize the progress bar without affecting the design-intended
    // height of 6px. The alternative of specifying a `max-height: 6px` will unfortunately
    // also affect the width calculation and make it vanish altogether.
    Rectangle {
        y: parent.height / 2 - 3px;
        height: 6px;

        border-radius: 3px;
        background: DemoPalette.neutral-box;

        Rectangle {
            x:0;
            width: max(6px, root.progress * parent.width / 100);
            border-radius: parent.border-radius;
            background: DemoPalette.control-foreground;
        }
    }
}

component WidePrintQueueElement inherits Rectangle {
    in property <PrinterQueueItem> queue-item;

    callback cancel-job();
    callback pause-job();

    border-color: DemoPalette.neutral-box;
    border-radius: 14px;
    border-width: 2px;
    background: DemoPalette.background;

    GridLayout {
        padding: parent.border-radius;
        spacing: 3px;

        HorizontalLayout {
            width: 48%;
            Text {
                // TODO: text-transform: uppercase
                text: {
                    if (root.queue-item.progress > 0) {
                        @tr("{}% - {}",root.queue-item.progress, PrinterQueue.statusString(root.queue-item.status))
                    } else {
                        PrinterQueue.statusString(root.queue-item.status)
                    }
                }
                color: DemoPalette.text-secondary;
                font-size: DemoPalette.base-font-size * 0.75;
                font-weight: 700;
                letter-spacing: 1.56px;
                horizontal-stretch: 1;
            }

            ProgressBar {
                // Each progress bar should have the same size
                // In principle it should be the smaller size which would fit next to the text foe each entry
                // But since it is too hard to compute, just hardcode that for now
                width: 50%; // 164px;
                progress: root.queue-item.progress;
            }
        }

        Text {
            col: 0;
            row: 1;
            text: root.queue-item.title;
            color: DemoPalette.text-primary;
            overflow: elide;
            font-weight: 700;
            font-size: DemoPalette.base-font-size * 1.125;
            horizontal-stretch: 1;
        }

        HorizontalLayout {
            col: 0;
            row: 3;
            spacing: 14px;
            horizontal-stretch: 1;
            vertical-stretch: 0;

            PushButton {
                clicked => { root.pause-job(); }

                text: @tr("Pause");
                icon: @image-url("images/pause.svg");
            }

            PushButton {
                clicked => { root.cancel-job(); }
                primary: false;
                text: @tr("Delete");
                icon: @image-url("images/delete.svg");
            }
        }

        PrintDetails {
            row: 0;
            col: 2;
            rowspan: 4;
            width: 40%;
            padding: 0px;
            padding-bottom: root.border-radius / 2;
            queue-item: root.queue-item;
            horizontal-stretch: 1;
        }
    }
}


export component WidePrinterQueueList inherits Flickable {
    VerticalLayout {
        alignment: start;
        padding: 0px;
        spacing: 13.5px;

        for queue-item[idx] in PrinterQueue.printer-queue: WidePrintQueueElement {
            cancel-job => { PrinterQueue.cancel-job(idx) }
            pause-job => { PrinterQueue.pause-job(idx) }

            queue-item: queue-item;
        }
    }
}

export component PrinterQueueView inherits Rectangle {
    callback show-job-details(int);

    border-radius: 27px;
    background: DemoPalette.background.darker(20%);

    VerticalLayout {
        padding: 16px;
        spacing: 16px;

        Text {
            text: @tr("Printing Queue");
            color: DemoPalette.text-primary;
            font-size: DemoPalette.base-font-size * 1.5;
            font-weight: 700;
        }

        queue-list := NarrowPrinterQueueList {
            show-job-details(idx) => {
                root.show-job-details(idx)
            }

            width: root.width - 2*parent.padding; // FIXME why do we need this? bug in layout?
        }
    }
}
